﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SplashModule.cs" company="http://buginbox.wordpress.com/">
//   Copyright (c) GNU General Public License version 2 (GPLv2)
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.MefExtensions.Modularity;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.ServiceLocation;
using Module.Splash.Event;
using Module.Splash.View;

namespace Module.Splash
{
    /// <summary>
    /// Splash Module
    /// </summary>
    [ModuleExport(typeof(SplashModule))]
    public class SplashModule : IModule
    {
        #region ctors

        /// <summary>
        /// Initializes a new instance of the <see cref="SplashModule"/> class.
        /// </summary>
        [ImportingConstructor]
        public SplashModule()
        {
        }

        #endregion

        #region Private Properties

        /// <summary>
        /// Gets or sets WaitForCreation.
        /// </summary>
        private AutoResetEvent WaitForCreation
        {
            get;
            set;
        }

        #endregion

        /// <summary>
        /// Initializes this instance.
        /// </summary>
        public void Initialize()
        {
            var watch = new Stopwatch();

            var eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();

            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() =>
                {
                    eventAggregator.GetEvent<CloseSplashEvent>().Publish(new CloseSplashEvent());
                    Application.Current.MainWindow.Show();
                    Application.Current.MainWindow.Activate(); // Be sure the shell is the new active window.

                    watch.Stop();
                }));

            WaitForCreation = new AutoResetEvent(false);

            ThreadStart showSplash = () =>
                {
                    Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() =>
                        {
                            watch.Start();

                            eventAggregator.GetEvent<CloseSplashEvent>().Subscribe(e => SplashViewModel.SplashView.Dispatcher.BeginInvoke((Action)SplashViewModel.SplashView.Close),
                                                                                   ThreadOption.PublisherThread, true);

                            SplashViewModel.ShowView();

                            WaitForCreation.Set();
                        }));

                    Dispatcher.Run();
                };

            var thread = new Thread(showSplash) { Name = "Splash Thread", IsBackground = true };
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();

            WaitForCreation.WaitOne();
        }

        /// <summary>
        /// Gets or sets the main view model.
        /// </summary>
        /// <value>
        /// The main view model. 
        /// </value>
        [Import]
        public SplashViewModel SplashViewModel
        {
            get;
            set;
        }
    }
}